#include <glib.h>

typedef struct foobar_tag {
    gint foo;
    gchar bar[4];
    gchar *str;
}foobar_t;

static void _array_free_func(gpointer data)
{
    foobar_t *foobar = (foobar_t *)data;

    if(NULL != foobar) {
        g_free(foobar->str);
    }

    //g_free(foobar); //Caution: can not free foobar here
}

gint main(gint argc, gchar **argv)
{
    GArray *arr = NULL;
    foobar_t *foobar[3] = {NULL, NULL, NULL};
    gint i = 0;
    guint n = 0;

    arr = g_array_new(FALSE, FALSE, sizeof(foobar_t));
    n = g_array_get_element_size(arr);
    g_print("element size:%d, array len:%d \n", n, arr->len);

    foobar[0] = g_new0(foobar_t, 1);
    foobar[1] = g_new0(foobar_t, 1);
    foobar[2] = g_new0(foobar_t, 1);

    foobar[0]->foo = 2;
    foobar[1]->foo = 3;
    foobar[2]->foo = 1;
    
    g_strlcpy(foobar[0]->bar, "ab", 4);
    g_strlcpy(foobar[1]->bar, "AAA", 4);
    g_strlcpy(foobar[2]->bar, "c", 4);

    foobar[0]->str = g_strdup("aaab");
    foobar[1]->str = g_strdup("AAAAAA");
    foobar[2]->str = g_strdup("c");

    g_array_append_val(arr, *foobar[0]); // Not foobar[0]
    g_array_append_val(arr, *foobar[1]);
    g_array_append_val(arr, *foobar[2]);

    // Caution: only the first element can be added success
    //g_array_append_vals(arr, *foobar, 3);  

    n = g_array_get_element_size(arr);
    g_print("element size:%d, array len:%d \n", n, arr->len);

    for(i=0; i<arr->len; i++) {
        g_print("arr[%d]:foo=%d,bar=%s,str=%s(addr:%p) \n", i, 
            (g_array_index(arr, foobar_t, i)).foo, 
            (g_array_index(arr, foobar_t, i)).bar,
            (g_array_index(arr, foobar_t, i)).str,
            &g_array_index(arr, foobar_t, i));
    }

    g_array_set_clear_func(arr, _array_free_func);
    g_free(foobar[0]);
    g_free(foobar[1]);
    g_free(foobar[2]);
    g_array_free(arr, TRUE);

    return 0;
}